﻿using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.DataAccess;
using Kiiro.ExceptionManagement;
using Kiiro.Validation.Validators.Entities;

namespace Kiiro.Model
{
    public class CommentModel
    {
        public static Comment GetById ( int commentId, Guid siteCollectionId, string serverRelativeUrl )
        {
            Comment comment = null;
            List<Comment> comments = GetCommentsByIds( new List<int>( ) { commentId }, siteCollectionId, serverRelativeUrl );

            if ( comments.Count > 0 )
                comment = comments[0];

            return comment;
        }

        /// <summary>
        /// Gets a list of Comment entities. If commentIds is null or empty this method returns ALL Comments.
        /// </summary>
        /// <param name="commentIds">The list of comment ids to get. If commentIds is null or empty this method returns ALL comments.</param>
        /// <param name="siteCollectionId">The site collection id</param>
        /// <param name="serverRelativeUrl">The server relative url</param>
        /// <returns>If commentIds is null or empty this method returns ALL comments.</returns>
        public static List<Comment> GetCommentsByIds ( List<int> commentIds, Guid siteCollectionId, string serverRelativeUrl )
        {
            List<Comment> comments = CommentDA.Instance.GetCommentsByIds( commentIds, siteCollectionId, serverRelativeUrl );

            if ( comments.Count > 0 )
            {
                // TODO: GetTeamMembers won't return TeamMembers for deleted Users
                List<TeamMember> members = TeamModel.GetTeamMembers( siteCollectionId, serverRelativeUrl );
                TeamMember member = null;

                // re-link CreatedBy and ModifiedBy properties
                foreach ( Comment comment in comments )
                {
                    if ( comment.CreatedBy != null && comment.CreatedBy.Id != default( int ) )
                    {
                        member = members.Find( m => m.UserId == comment.CreatedBy.Id );
                        if ( member != null )
                        {
                            comment.CreatedBy = member.User;
                        }
                    }

                    if ( comment.ModifiedBy != null && comment.ModifiedBy.Id != default( int ) )
                    {
                        member = members.Find( m => m.UserId == comment.CreatedBy.Id );
                        if ( member != null )
                        {
                            comment.CreatedBy = member.User;
                        }
                    }
                }
            }

            return comments;
        }

        public static Comment Save ( Comment comment, Guid siteCollectionId, string serverRelativeUrl )
        {
            try
            {
                if ( comment != null && comment.EditType != EditType.Unchanged )
                {
                    PermissionsModel.GetGlobalPermissionBitsForCurrentUser ( comment, comment.ModifiedBy, siteCollectionId, serverRelativeUrl, false );

                    if ( comment.PermissionBitsDiscussions != null && comment.PermissionBitsDiscussions.Count == 4
                        && ( comment.PermissionBitsDiscussions [ 0 ] || comment.PermissionBitsDiscussions [ 2 ] || comment.PermissionBitsDiscussions [ 3 ] ) )
                    {
                        new CommentValidator ( ).Validate ( comment );

                        if ( comment.EditType == EditType.Deleted || comment.IsValid ( ) )
                        {
                            Comment deletedComment = new Comment();

                            List<Attachment> attachments = comment.AttachmentList;

                            if (comment.EditType == EditType.Deleted)
                            {
                                deletedComment = comment;
 
                                CommentDA.Instance.Save(comment, siteCollectionId, serverRelativeUrl);
                                Discussion discussion = DiscussionModel.GetById(deletedComment.DiscussionId, siteCollectionId, serverRelativeUrl);
                                if (discussion.Comments.Count > 1)
                                {
                                    discussion.Comments.Sort(delegate(Comment c1, Comment c2) { return c2.ModifiedDate.CompareTo(c1.ModifiedDate); }); ;
                                }
                                if (discussion.LastCommentDate > DateTime.Now.AddDays(-7)
                                    || discussion.LastCommentDate == discussion.CreatedDate)
                                {
                                    Midori midori = new Midori();
                                    discussion.EditType = EditType.Updated;
                                    midori.Discussions.Add(discussion);
                                    midori.Comments.Add(deletedComment);
                                    ProjectsModel.UpdateProjectStatistics(midori, siteCollectionId, serverRelativeUrl);
                                }         
                   

                            }
                            if (comment.EditType != EditType.Deleted)
                            {
                                EditType commentEditeType = comment.EditType;
                                comment = CommentDA.Instance.Save ( comment, siteCollectionId, serverRelativeUrl );

                                comment.AttachmentList = attachments;
                                if (comment.EditType != EditType.Deleted)
                                    AttachmentModel.SaveAttachments(comment, siteCollectionId, serverRelativeUrl);

                                comment.EditType = commentEditeType;
                                Discussion discussion = DiscussionModel.GetById(comment.DiscussionId, siteCollectionId, serverRelativeUrl);

                                if (discussion.Comments.Count > 1)
                                {
                                    discussion.Comments.Sort(delegate(Comment c1, Comment c2) { return c2.ModifiedDate.CompareTo(c1.ModifiedDate); }); ;
                                }
                                // email users about new comment
                                EmailModel.Instance.SendDiscussionCommentAddedEmail(discussion, siteCollectionId, serverRelativeUrl, comment.ModifiedBy);

                                if (discussion.LastCommentDate > DateTime.Now.AddDays(-7)
                                    || discussion.LastCommentDate == discussion.CreatedDate)
                                {
                                    Midori midori = new Midori();
                                    discussion.EditType = EditType.Updated;
                                    midori.Discussions.Add(discussion);
                                    midori.Comments.Add(comment);
                                    ProjectsModel.UpdateProjectStatistics(midori, siteCollectionId, serverRelativeUrl);
                                }
                            }
                        }
                    }
                    else
                        throw new KiiroUnauthorizedAccessException ( "Updating Comment Failed: Access Denied." );
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }

            return comment;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Model/CommentModel.cs $
 * 
 * 11    17/08/09 10:29a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/